﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SGT_DAL._STG_DALTableAdapters;
using SGT_DAL;
using System.Threading;
using System.Globalization;

namespace SGT_ON
{
    /// <summary>
    /// Va a contener todo lo referido a la administración de hilos
    /// </summary>
    public partial class Alerta
    {
        private static Thread _alertasPorElementosSinAsignar;
        private static Thread _alertasVariasCada12Hs;

        static volatile bool _detenerAlertasPorElementosSinAsignar = false;
        static volatile bool _detenerAlertasVariasCada12Hs = false;
        /// <summary>
        /// Inicia todos los hilos del sistema.
        /// </summary>
        public static void IniciarTodosLosHilos()
        {
            IniciarHiloAlertasPorElementosSinAsignar();
            IniciarHiloAlertaVariasCada12Hs();
        }

        #region Hilo Elementos sin asignar
        /// <summary>
        /// Inicia el hilo de las alertas para los elementos que estan sin asignar
        /// </summary>
        public static void IniciarHiloAlertasPorElementosSinAsignar()
        {
            //////////////////////////////////////////////////////
            // HILO DE ELEMENTOS SIN ASIGNAR
            DetenerHiloAlertasPorElementosSinAsignar();

            _alertasPorElementosSinAsignar = new Thread(GenerarAlertasPorElementosSinAsignar);
            _alertasPorElementosSinAsignar.Start();
            _detenerAlertasPorElementosSinAsignar = false;
            // FIN HILO DE ELEMENTOS SIN ASIGNAR
            /////////////////////////////////////////////////////
        }
        public static void DetenerHiloAlertasPorElementosSinAsignar()
        {
            if (_alertasPorElementosSinAsignar == null)
                return;

            _detenerAlertasPorElementosSinAsignar = true;
            _alertasPorElementosSinAsignar.Abort();
        }
        public static void GenerarAlertasPorElementosSinAsignar()
        {
            do
            {
                //espero 3 minutos para que no se ejecuten todos los procesos juntos.
                Thread.Sleep(3 * 60 * 1000); //de milisegundos a minutos

                if (Parametros.DetenerTodosLosHilosConAccesoADatos == false) // verifico si he detenido todos los hilos manualmente
                {
                    // Genero las alertas
                    GenerarAlertaPorElementosSinAsignar();
                }

                // Espero el tiempo preestablecido
                Thread.Sleep(Parametros.AlertaPorElementosSinAsignarAutomaticamenteCadaMinutos * 60 * 1000); //de milisegundos a minutos
            }
            while (_detenerAlertasPorElementosSinAsignar == false);
        }
        #endregion

        #region Hilo Alertas varias
        /// <summary>
        /// Inicia el hilo de las alertas para los presupuestos que se tienen que entregar por la fecha de entrega.
        /// 
        /// </summary>
        public static void IniciarHiloAlertaVariasCada12Hs()
        {
            //////////////////////////////////////////////////////
            // Hilo Alertas por vehículos que se tienen que entregar pronto
            DetenerHiloAlertaVariasCada12Hs();

            _alertasVariasCada12Hs = new Thread(GenerarAlertasVariasCada12Hs);
            _alertasVariasCada12Hs.Start();
            _detenerAlertasVariasCada12Hs = false;
            // FIN Hilo Alertas por vehículos que se tienen que entregar pronto
            /////////////////////////////////////////////////////
        }
        public static void DetenerHiloAlertaVariasCada12Hs()
        {
            if (_alertasVariasCada12Hs == null)
                return;

            _detenerAlertasVariasCada12Hs = true;
            _alertasVariasCada12Hs.Abort();
        }
        public static void GenerarAlertasVariasCada12Hs()
        {
            do
            {
                if (Parametros.DetenerTodosLosHilosConAccesoADatos == false) // verifico si he detenido todos los hilos manualmente
                {
                    // espero 5 minutos para que no se ejecuten todos los procesos simultanemante.
                    Thread.Sleep(5 * 60 * 1000); //5 minutos pasados a milisegundos

                    // Genero las alertas por presupuestos a punto de entregar.
                    GenerarAlertaPresupuestosAPuntoDeEntregar();

                    // Genero alertas por presupuetos facturados o anotados que ya tendrian que haber sido cobrados.
                    GenerarAlertasPorPresupuestosQueTienenQueHaberSidoCobrados();

                    //OC-017-12: 27 Procesos automáticos: Todos los presupuestos que están en estado Presupuesto por más
                    //de X cantidad de meses, se cambiarán automáticamente al estado Cerrado
                    PasarPresupuestosDePresupuestoACerrado();

                    //OC-017-12 - 26:Procesos automáticos: Todos los presupuestos que están en estado Borrador por más de X
                    //cantidad de días (definido en los parámetros del sistema) serán cambiados automáticamente a estado Presupuesto
                    PasarPresupuestosDeBorradorAPresupuesto();
                }
                // Espero el tiempo preestablecido
                Thread.Sleep(1 * 60 * 60 * 1000); //1 horas pasadas a milisegundos
            }
            while (_detenerAlertasVariasCada12Hs == false);
        }
    }
    /// <summary>
    /// Clase utilizada para la presentación y propiedades derivadas.
    /// </summary>
    public partial class Alerta
    {
        public int IdPresupuesto
        {
            get
            {
                //Verifico que la alerta sea de presupuesto
                if (idReferenciaConTabla.Contains("Presupuesto") == false)
                    return -1;

                int _resultado = int.Parse(idReferenciaConTabla.Replace("Presupuesto", ""));

                return _resultado;
            }
        }
        public string FechaSilenciadaString
        {
            get
            {
                if (FechaSilenciada <= Parametros.FechaMinima)
                    return "";
                return FechaSilenciada.ToString("dd/MM/yyyy");
            }
        }
        public string PatenteParaAlertas
        {
            get
            {
                int _idPresupuestoAsociado = IdPresupuesto;

                if (_idPresupuestoAsociado < 0)
                    return "Presupuesto no encontrado";

                ONPresupuesto _presupuesto = ONPresupuesto.CrearPresupuesto(_idPresupuestoAsociado);

                if ((_presupuesto == null)
                    || (_presupuesto.ID <= 0))
                    return "Presupuesto no encontrado";

                string _resultado = _presupuesto.Patente;

                return _resultado;
            }
        }

        public string FechaEntregaEstimadaParaAlertas
        {
            get
            {
                int _idPresupuestoAsociado = IdPresupuesto;

                if (_idPresupuestoAsociado < 0)
                    return "Presupuesto no encontrado";

                ONPresupuesto _presupuesto = ONPresupuesto.CrearPresupuesto(_idPresupuestoAsociado);

                if ((_presupuesto == null)
                    || (_presupuesto.ID <= 0))
                    return "Presupuesto no encontrado";
                
                if (_presupuesto.FechaEntregaEstimada <= Parametros.FechaMinima)
                    return "Sin fecha de entrega";

                CultureInfo ci = new CultureInfo("Es-Es");
                string _dia = (ci.DateTimeFormat.GetDayName(_presupuesto.FechaEntregaEstimada.Value.DayOfWeek)) + " " + _presupuesto.FechaEntregaEstimadaString;
                _dia = _dia.Substring(0, 1).ToUpper() + _dia.Substring(1,2);

                string _resultado;
                _resultado = _dia + ". " + _presupuesto.FechaEntregaEstimada.Value.ToString("dd/MM");

                return _resultado;
            }
        }
        public DateTime PresupuestoFechaEntregaEstimada
        {
            get
            {
                int _idPresupuestoAsociado = IdPresupuesto;

                if (_idPresupuestoAsociado < 0)
                    return Parametros.FechaMinima;

                ONPresupuesto _presupuesto = ONPresupuesto.CrearPresupuesto(_idPresupuestoAsociado);

                if ((_presupuesto == null)
                    || (_presupuesto.ID <= 0))
                    return Parametros.FechaMinima;

                if (_presupuesto.FechaEntregaEstimada <= Parametros.FechaMinima)
                    return Parametros.FechaMinima;

                return _presupuesto.FechaEntregaEstimada.Value;

            }
        }
        /// <summary>
        /// Texto que se va a mostrar en el tooltip de las alertas
        /// </summary>
        public string ToolTip
        {
            get
            {
                string _toolTip;
                if (IdPresupuesto <= 0)
                    return "Presupuesto no encontrado";

                ONPresupuesto _presupuesto = ONPresupuesto.CrearPresupuesto(this.IdPresupuesto);
                _toolTip = _presupuesto.ApellidoYNombre + Environment.NewLine;
                _toolTip = _toolTip + _presupuesto.Marca + Environment.NewLine;
                _toolTip = _toolTip + _presupuesto.Modelo + Environment.NewLine;
                _toolTip = _toolTip + _presupuesto.CelularTelefono + Environment.NewLine;
                _toolTip = _toolTip + _presupuesto.ProveedorDeRepuestos;

                return _toolTip;
            }
        }
        /// <summary>
        /// Es el importe de la factura
        /// </summary>
        public string Importe
        {
            get
            {
                int _idPresupuestoAsociado = IdPresupuesto;

                if (_idPresupuestoAsociado < 0)
                    return "Presupuesto no encontrado";

                ONPresupuesto _presupuesto = ONPresupuesto.CrearPresupuesto(_idPresupuestoAsociado);

                if ((_presupuesto == null)
                    || (_presupuesto.ID <= 0))
                    return "Presupuesto no encontrado";

                
                if(_presupuesto.TotalAutorizadoString != "")
                    return "$ " + _presupuesto.TotalAutorizadoString;
                else
                    return "$ " + _presupuesto.TotalOriginalString;
                
            }
        }
        /// <summary>
        /// Es el Numero de factura
        /// </summary>
        public string NumeroFactura
        {
            get
            {
                int _idPresupuestoAsociado = IdPresupuesto;

                if (_idPresupuestoAsociado < 0)
                    return "Presupuesto no encontrado";

                ONPresupuesto _presupuesto = ONPresupuesto.CrearPresupuesto(_idPresupuestoAsociado);

                if ((_presupuesto == null)
                    || (_presupuesto.ID <= 0))
                    return "Presupuesto no encontrado";

                return _presupuesto.FacturaDeVenta;
            }
        }
        public string ToolTipNoCobrado
        {
            get
            {
                string _toolTip;
                if (IdPresupuesto <= 0)
                    return "Presupuesto no encontrado";

                ONPresupuesto _presupuesto = ONPresupuesto.CrearPresupuesto(this.IdPresupuesto);
                _toolTip = "Facturado: " + _presupuesto.FechaFacturacionString + Environment.NewLine;
                _toolTip = _toolTip + "Número factura: " + _presupuesto.FacturaDeVenta + Environment.NewLine;
                _toolTip = _toolTip + "Compañía: " + _presupuesto.AseguradoraRazonSocial + Environment.NewLine;
                _toolTip = _toolTip + "Importe: " + Importe + Environment.NewLine;
                _toolTip = _toolTip + "Siniestro: " + _presupuesto.NumeroDeSiniestro + Environment.NewLine;
                _toolTip = _toolTip + "Patente: " + _presupuesto.Patente;

                return _toolTip;
            }
        }
    }
    /// <summary>
    /// Clase base con la lógica de negocio
    /// </summary>
    [System.ComponentModel.DataObject]
    public partial class Alerta
    {
        public enum Origenes
        {
            Entrega_próxima,
            Stock,
            No_cobrado
        }
        
        #region Atributos
        protected int _id;
        protected string _RolAsociado;
        protected string _Descripcion;
        protected string _Detalle;
        protected DateTime _FechaActivacion;
        protected DateTime _FechaSilenciada;
        protected string _SilenciadaPor;
        protected string _URLAsociada;
        protected string _idReferenciaConTabla;
        protected string _Origen;
        protected short _Importancia;
        protected int _EmpleadoIdResponsable;

        //Objetos asociados
        #endregion

        #region Propiedades
        public int ID
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value;
            }
        }
        public string RolAsociado
        {
            get
            {
                return _RolAsociado;
            }
            set
            {
                _RolAsociado = value;
            }
        }
        public string Descripcion
        {
            get
            {
                return _Descripcion;
            }
            set
            {
                _Descripcion = value;
            }
        }
        public string Detalle
        {
            get
            {
                return _Detalle;
            }
            set
            {
                _Detalle = value;
            }
        }
        public DateTime FechaActivacion
        {
            get
            {
                return _FechaActivacion;
            }
            set
            {
                _FechaActivacion = value;
            }
        }
        public DateTime FechaSilenciada
        {
            get
            {
                return _FechaSilenciada;
            }
            set
            {
                _FechaSilenciada = value;
            }
        }
        public string SilenciadaPor
        {
            get
            {
                return _SilenciadaPor;
            }
            set
            {
                _SilenciadaPor = value;
            }
        }
        public string URLAsociada
        {
            get
            {
                return _URLAsociada;
            }
            set
            {
                _URLAsociada = value;
            }
        }
        public string idReferenciaConTabla
        {
            get
            {
                return _idReferenciaConTabla;
            }
            set
            {
                _idReferenciaConTabla = value;
            }
        }
        public string Origen
        {
            get
            {
                return _Origen;
            }
            set
            {
                _Origen = value;
            }
        }
        public short Importancia
        {
            get
            {
                return _Importancia;
            }
            set
            {
                _Importancia = value;
            }
        }
        public int EmpleadoIdResponsable
        {
            get
            {
                return _EmpleadoIdResponsable;
            }
            set
            {
                _EmpleadoIdResponsable = value;
            }
        }
        //Objetos asociados

        //Propiedades derivadas
        #endregion

        #region Interfase DAL
        //objeto de la capa DAL
        private static AlertaTableAdapter _AlertaAD;
        protected static AlertaTableAdapter Adaptador
        {
            get
            {
                if (_AlertaAD == null)
                    _AlertaAD = new AlertaTableAdapter();

                return _AlertaAD;
            }
        }
        public static Alerta ObtenerPorID(int pID)
        {
            _STG_DAL.AlertaDataTable _dt;

            _dt = Adaptador.ObtenerPorId(pID);

            // si tiene algo,
            if (_dt.Rows.Count > 0)
                return AsignarRowAObjeto((_STG_DAL.AlertaRow)_dt.Rows[0]);

            return null;
        }
        protected static Alerta AsignarRowAObjeto(_STG_DAL.AlertaRow pRow)
        {
            Alerta _Alerta = new Alerta();
            if (pRow != null)
            {
                _Alerta = new Alerta();
                _Alerta.ID = pRow.ID;
                _Alerta.RolAsociado = pRow.RolAsociado;
                _Alerta.Descripcion = pRow.Descripcion;
                _Alerta.Detalle = pRow.Detalle;
                _Alerta.FechaActivacion = pRow.FechaActivacion;
                _Alerta.FechaSilenciada = pRow.FechaSilenciada;
                _Alerta.SilenciadaPor = pRow.SilenciadaPor;
                _Alerta.URLAsociada = pRow.URLAsociada;
                _Alerta.idReferenciaConTabla = pRow.idReferenciaConTabla;
                _Alerta.Origen = pRow.Origen;
                _Alerta.Importancia = pRow.Importancia;
                _Alerta.EmpleadoIdResponsable = pRow.EmpleadoIdResponsable;
            }
            return _Alerta;
        }
        protected static int Insertar(string pRolAsociado, string pDescripcion, string pDetalle, DateTime pFechaActivacion, DateTime pFechaSilenciada, string pSilenciadaPor, string pURLAsociada, string pIdReferenciaConTabla, string pOrigen, short pImportancia, int pEmpleadoIdResponsable)
        {
            return int.Parse(Adaptador.Insertar(pRolAsociado, pDescripcion, pDetalle, pFechaActivacion, pFechaSilenciada, pSilenciadaPor, pURLAsociada, pIdReferenciaConTabla, pOrigen, pImportancia, pEmpleadoIdResponsable).ToString());
        }
        public static bool Actualizar(string pRolAsociado, string pDescripcion, string pDetalle, DateTime pFechaActivacion, DateTime pFechaSilenciada, string pSilenciadaPor, string pURLAsociada, string pIdReferenciaConTabla, string pOrigen, short pImportancia,int pEmpleadoIdResponsable, int pID)
        {
            if (0 < Adaptador.Actualizar(pRolAsociado, pDescripcion, pDetalle, pFechaActivacion, pFechaSilenciada, pSilenciadaPor, pURLAsociada, pIdReferenciaConTabla, pOrigen, pImportancia, pEmpleadoIdResponsable, pID))
                return true;
            else
                return false;
        }
        public bool Actualizar()
        {
            return Actualizar(RolAsociado, Descripcion, Detalle, FechaActivacion, FechaSilenciada, SilenciadaPor, URLAsociada, idReferenciaConTabla, Origen, Importancia, EmpleadoIdResponsable, ID);
        }
        //public void EliminarDAL()
        //{
        //    Alerta _Alerta = Alerta.ObtenerPorID(this.ID);
        //    _Alerta.EstaActivo = false;
        //    _Alerta.Actualizar();
        //}
        protected static AlertaColeccion AsignarAlertaTableAdapterAAlertaColeccion(_STG_DAL.AlertaDataTable pDataTable)
        {
            AlertaColeccion _Alertaes = new AlertaColeccion();
            Alerta _Alerta;

            if ((pDataTable != null)
                && (pDataTable.Rows.Count > 0))
            {
                foreach (_STG_DAL.AlertaRow _row in pDataTable.Rows)
                {
                    _Alerta = AsignarRowAObjeto(_row);
                    if (_Alerta != null)
                        _Alertaes.Add(_Alerta);
                }
            }
            return _Alertaes;
        }
        public static AlertaColeccion ObtenerAlertasActivas()
        {
            return AsignarAlertaTableAdapterAAlertaColeccion(Adaptador.ObtenerAlertasActivas());
        }
        public static AlertaColeccion ObtenerTodasEntreFechas(DateTime pFechaDesde, DateTime pFechaHasta)
        {
            // si no se especificaron, se devuelve vacio
            if ((pFechaDesde == pFechaHasta)
                && (pFechaHasta == Parametros.FechaMinima))
                return new AlertaColeccion();

            pFechaDesde = pFechaDesde.Date;
            pFechaHasta = pFechaHasta.AddDays(1).AddSeconds(-1);

            return AsignarAlertaTableAdapterAAlertaColeccion(Adaptador.ObtenerTodasEntreFechas(pFechaDesde, pFechaHasta));
        }
        /// <summary>
        /// Devuelve todas las alertas activas que tiene el IdReferenciaConTabla
        /// </summary>
        /// <param name="pIdReferenciaConTabla"></param>
        /// <returns></returns>
        public static AlertaColeccion ObtenerPorIdReferenciaConTabla(string pIdReferenciaConTabla)
        {
            return AsignarAlertaTableAdapterAAlertaColeccion(Adaptador.ObtenerPorIdReferenciaConTabla(pIdReferenciaConTabla));
        }
        /// <summary>
        /// Obtiene todas las alertas activas del empleado.
        /// </summary>
        /// <param name="pEmpleadoIdResponsable"></param>
        /// <returns></returns>
        public static AlertaColeccion ObtenerPorEmpleadoIdResponsable(int pEmpleadoIdResponsable)
        {
            AlertaColeccion _alertas = AsignarAlertaTableAdapterAAlertaColeccion(Adaptador.ObtenerPorEmpleadoIdResponsable(pEmpleadoIdResponsable));
            _alertas.OrdenarPorFecha();
            return _alertas;
        }
        /// <summary>
        /// Obtiene todas las alertas de presupuestos no cobrados.
        /// </summary>
        /// <returns></returns>
        public static AlertaColeccion ObtenerNoCobradas()
        {
            return AsignarAlertaTableAdapterAAlertaColeccion(Adaptador.ObtenerNoCobradas());
        }
        /// <summary>
        /// Devuelve la cantidad de alertas activas que hay en el sistema.
        /// </summary> 
        public static int CantidadDeAlertasActivas
        {
            get
            {
                int? _cantidadDeAlertas = Adaptador.ObtenerCantidadDeAlertasActivas();
                if (_cantidadDeAlertas.HasValue == false)
                    return 0;
                else
                    return _cantidadDeAlertas.Value;
            }
        }
        public static bool HayAlertasActivas
        {
            get
            {
                if (CantidadDeAlertasActivas > 0)
                    return true;
                else
                    return false;

            }
        }
        #endregion

        #region Métodos
        public Alerta()
        {
            AsignarValoresIniciales();
        }

        public void AsignarValoresIniciales()
        {
            _id = -1;
            RolAsociado = "";
            Descripcion = "";
            Detalle = "";
            FechaActivacion = Parametros.FechaMinima;
            FechaSilenciada = Parametros.FechaMinima;
            SilenciadaPor = "";
            URLAsociada = "";
            idReferenciaConTabla = "";
            Origen = "";
            Importancia = 5;
        }

        public int Insertar()
        {
            return Insertar(RolAsociado, Descripcion, Detalle, FechaActivacion, FechaSilenciada, SilenciadaPor, URLAsociada, idReferenciaConTabla, Origen, Importancia, EmpleadoIdResponsable);
        }

        /// <summary>
        /// Reliza una búsqueda de todos los productos de stock asignados a presupuestos que no fueron entregados
        /// </summary>
        public static void BuscarYGenerarNuevasAlertas()
        {
            //Generar alerta para todos los elementos que quedaron sin entregar
            GenerarAlertaPorElementosSinAsignar();
        }
        /// <summary>
        /// Generar alerta para todos los elementos que quedaron sin entregar
        /// Condiciones:
        ///     - Presupuesto en estado: Cancelado | Facturado | Cobrado | Cerrado
        ///     - Producto de stock asignado a un elemento
        ///     - Producto de stock marcado como no entregado
        /// </summary>
        private static void GenerarAlertaPorElementosSinAsignar()
        {
            string _rolAsociado, _descripcion, _detalle, _silenciadaPor, _urlAsociada, _idReferenciaConTabla, _origen;
            DateTime _fechaActivacion, _fechaSilenciada;
            short _importancia;

            StockMovimientoStockColeccion _movimientos = StockMovimientoStock.ObtenerElementosEnDeposito();

            // Rol asociado
            _rolAsociado = "Administración";
            _silenciadaPor = "";
            _origen = "Stock";
            _fechaActivacion = DateTime.Now;
            _fechaSilenciada = Parametros.FechaMinima;
            _importancia = 7;

            StockProductoEnPresupuesto _productoEnPresupuesto;
            ONPresupuesto _presupuesto;
            foreach (StockMovimientoStock _ms in _movimientos)
            {
                _productoEnPresupuesto = StockProductoEnPresupuesto.ObtenerPorIdMovimientoDeStock(_ms.ID);
                _presupuesto = ONPresupuesto.CrearPresupuesto(_productoEnPresupuesto.ElementoAsociado.IdPresupuesto);
                _descripcion = _ms.Producto.Nombre + " en depósito y asociado al presupuesto " + _presupuesto.Patente + " cuyo estado es " + _presupuesto.Estado;
                _detalle = (int.Parse(_ms.DiferenciaStock) * -1).ToString() + " " + _ms.Producto.UnidadDeMedida + " de " + _ms.Producto.Nombre + " estan asignadas al presupuesto de patente " + _presupuesto.Patente + " que se encuentra en estado " + _presupuesto.Estado + ". En este estado, el presupuesto no debería tener productos asociados que estén en depósito, debe liberar el producto del presupuesto o marcarlo como entregado.";
                _urlAsociada = "Presupuesto.aspx?ID=" + _presupuesto.ID.ToString();
                _idReferenciaConTabla = _ms.ID.ToString() + "StockMovimientoDeStock";
                Alerta.Insertar(_rolAsociado, _descripcion, _detalle, _fechaActivacion, _fechaSilenciada, _silenciadaPor, _urlAsociada, _idReferenciaConTabla, _origen, _importancia, _presupuesto.UsuarioResponsableId);
            }

            
        }
        /// <summary>
        /// Se agregará la siguiente alerta automática al módulo actual de alertas: Los
        /// presupuestos mostrados serán aquellos en los que el usuario activo es responsable cumplan con la siguiente condición:
        ///  - La fecha de entrega del vehículo es menor o igual a la fecha actual más X cantidad de días
        ///  (configurable en los parámetros del sistema). Ej: siendo X = 1 día, se muestran todos los
        ///  presupuestos que tengan fecha de entrega menor igual al día de mañana.
        ///  - El presupuesto tiene que estar en estado "En reparación"
        /// </summary>
        private static void GenerarAlertaPresupuestosAPuntoDeEntregar()
        {
            string _rolAsociado, _descripcion, _detalle, _silenciadaPor, _urlAsociada, _idReferenciaConTabla, _origen;
            DateTime _fechaActivacion, _fechaSilenciada;
            short _importancia;

            DateTime _fechaMaxima =  DateTime.Today.AddDays(Parametros.DiasAlertaDeEntrega + 1).AddSeconds(-1);
            ONPresupuestoColeccion _presupuestos = ONPresupuesto.ObtenerPresupuestosConEntregaProxima(ONPresupuesto.enuEstados.Reparación.ToString(), _fechaMaxima, Origenes.Entrega_próxima.ToString().Replace("_", " "));

            // Rol asociado
            _rolAsociado = "Comercial";
            _silenciadaPor = "";
            _origen = Origenes.Entrega_próxima.ToString().Replace("_"," ");
            _fechaActivacion = DateTime.Now;
            _fechaSilenciada = Parametros.FechaMinima;
            _importancia = 7;

            foreach (ONPresupuesto _presupuesto in _presupuestos)
            {   
                _descripcion = _presupuesto.Patente + " se debe entregar " + _presupuesto.FechaEntregaEstimadaConDia;
                _detalle = _presupuesto.Patente + " se debe entregar " + _presupuesto.FechaEntregaEstimadaConDia;
                _urlAsociada = "Presupuesto.aspx?ID=" + _presupuesto.ID.ToString();
                _idReferenciaConTabla = _presupuesto.ID.ToString() + "Presupuesto";
                Alerta.Insertar(_rolAsociado, _descripcion, _detalle, _fechaActivacion, _fechaSilenciada, _silenciadaPor, _urlAsociada, _idReferenciaConTabla, _origen, _importancia, _presupuesto.UsuarioResponsableId);
            }


        }
        /// <summary>
        /// OC-017-12 Alertas - Rol comercial: Se generará la alerta si el estado del presupuesto es Facturado y la
        //  fecha de facturación / anotado más la cantidad de días definidos en los parámetros del
        //  sistema en la sección de compañías, es mayor a la fecha actual
        /// </summary>
        private static void GenerarAlertasPorPresupuestosQueTienenQueHaberSidoCobrados()
        {
            
            string _rolAsociado, _descripcion, _detalle, _silenciadaPor, _urlAsociada, _idReferenciaConTabla, _origen;
            DateTime _fechaActivacion, _fechaSilenciada;
            short _importancia;

            DateTime _fechaMaxima = DateTime.Today.AddDays(Parametros.DiasAlertaDeEntrega + 1).AddSeconds(-1);
            ONPresupuestoColeccion _presupuestos = ONPresupuesto.ObtenerPresupuestosConAlertaDeFacturacion(Origenes.No_cobrado.ToString().Replace("_", " "));

            // Rol asociado
            _rolAsociado = "Comercial";
            _silenciadaPor = "";
            _origen = Origenes.No_cobrado.ToString().Replace("_", " ");
            _fechaActivacion = DateTime.Now;
            _fechaSilenciada = Parametros.FechaMinima;
            _importancia = 7;

            foreach (ONPresupuesto _presupuesto in _presupuestos)
            {
                _descripcion = _presupuesto.Patente + " fecha de cobro " + (_presupuesto.FechaFacturacion.AddDays(_presupuesto.Aseguradora.DiasDuracionCuentaCorriente)).Date.ToString("dd/MM/yyyy") + ", monto " + _presupuesto.TotalOriginal.ToString(Parametros.FormatoDinero);
                _detalle = _presupuesto.Patente + " de " + _presupuesto.Aseguradora.RazonSocial + " se debe cobrar el " + (_presupuesto.FechaFacturacion.AddDays(_presupuesto.Aseguradora.DiasDuracionCuentaCorriente)).Date.ToString("dd/MM/yyyy") + ", monto " + _presupuesto.TotalOriginal.ToString(Parametros.FormatoDinero);
                _urlAsociada = "Presupuesto.aspx?ID=" + _presupuesto.ID.ToString();
                _idReferenciaConTabla = _presupuesto.ID.ToString() + "Presupuesto";
                Alerta.Insertar(_rolAsociado, _descripcion, _detalle, _fechaActivacion, _fechaSilenciada, _silenciadaPor, _urlAsociada, _idReferenciaConTabla, _origen, _importancia, _presupuesto.UsuarioResponsableId);
            }
        }
        /// <summary>
        /// Procesos automáticos: Todos los presupuestos que están en estado Borrador por más de X
        /// cantidad de días (definido en los parámetros del sistema) serán cambiados automáticamente a estado Presupuesto
        /// </summary>
        private static void PasarPresupuestosDeBorradorAPresupuesto()
        {
            DateTime _fechaDesde = DateTime.Today.AddDays(-1 * Parametros.DiasParaPasarDeBorradorAPresupuesto -1);
                        
            ONPresupuestoColeccion _presupuestos = ONPresupuesto.ObtenerPresupuestosPorFechaDesdeYEstado(ONPresupuesto.enuEstados.Borrador.ToString(), _fechaDesde);

            //Todos los presupuestos obtenidos tienen que ser cambiados de estado.
            foreach (ONPresupuesto _presupuesto in _presupuestos)
            {
                _presupuesto.Estado = ONPresupuesto.enuEstados.Presupuesto.ToString();
                _presupuesto.Actualizar();
            }

        }
        /// <summary>
        /// OC-017-12: 27 Procesos automáticos: Todos los presupuestos que están en estado Presupuesto por más
        /// de X cantidad de meses, se cambiarán automáticamente al estado Cerrado
        /// </summary>
        private static void PasarPresupuestosDePresupuestoACerrado()
        {
            DateTime _fechaDesde = DateTime.Today.AddMonths(-1 * Parametros.MesesParaPasarDePresupuestoACerrado);

            ONPresupuestoColeccion _presupuestos = ONPresupuesto.ObtenerPresupuestosPorFechaDesdeYEstado(ONPresupuesto.enuEstados.Presupuesto.ToString(), _fechaDesde);

            //Todos los presupuestos obtenidos tienen que ser cambiados de estado.
            foreach (ONPresupuesto _presupuesto in _presupuestos)
            {
                _presupuesto.Estado = ONPresupuesto.enuEstados.Cerrado.ToString();
                _presupuesto.Actualizar();
            }

        }

        #endregion

        #endregion

        #region Metodos para datasource

        //public void Actualizar(Alerta pAlerta)
        //{
        //    if (pAlerta != null)
        //        pAlerta.Actualizar();
        //}
        public Alerta Insertar(Alerta pAlerta)
        {
            if (pAlerta != null)
            {
                pAlerta.ID = pAlerta.Insertar();
                return pAlerta;
            }
            return null;
        }
        //public void Eliminar(Alerta pAlerta)
        //{

        //    pAlerta.EliminarDAL();
        //}
        #endregion
    }
    [System.ComponentModel.DataObject]
    public class AlertaColeccion : System.Collections.CollectionBase
    {
        public void Add(Alerta pAlerta)
        {
            this.List.Add(pAlerta);
        }
        public void AddUnico(Alerta pAlerta)
        {
            foreach (Alerta _Alerta in this)
                if (pAlerta.ID == _Alerta.ID)
                    return;
            this.List.Add(pAlerta);
        }
        public void Remove(int index)
        {
            if (index <= Count - 1 || index >= 0)
            {
                this.List.RemoveAt(index);
            }
            else
            {
                throw new System.ArgumentException("Fuera de rango", "original");
            }
        }
        public void Remove(Alerta pAlerta)
        {
            for (int i = 0; i < this.Count; i++)
            {
                if (this[i].ID == pAlerta.ID)
                {
                    Remove(i);
                    return;
                }

            }
        }
        public Alerta this[int index]
        {
            get { return ((Alerta)(this.List[index])); }
            set { this.List[index] = value; }
        }

        #region Ordenamiento de colecciones
        public void OrdenarPorFecha()
        {

            System.Collections.IComparer sorter = new OrdenarPorFechaHelper();

            InnerList.Sort(sorter);

        }
        private class OrdenarPorFechaHelper : System.Collections.IComparer
        {

            public int Compare(object x, object y)
            {

                Alerta p1 = (Alerta)x;

                Alerta p2 = (Alerta)y;

                if (p1.PresupuestoFechaEntregaEstimada > p2.PresupuestoFechaEntregaEstimada)
                    return 1;

                if (p1.PresupuestoFechaEntregaEstimada < p2.PresupuestoFechaEntregaEstimada)
                    return -1;

                return 0;
            }

        }
        #endregion
    }
}
